﻿using LibUsbDotNet.Main;

namespace GCC.Container.Abstracts
{
    /// <summary>
    /// 抽象的USB通信服务
    /// </summary>
    /// <typeparam name="T">通信数据类型</typeparam>
    /// <remarks>注意,由于串口得特殊性,不关析构了服务还是client,双方都将被联合析构,想要停止只能析构</remarks>
    public abstract class AbsCommUSBServer<T> : AbsCommServer, IDisposable
    {
        /// <summary>
        /// 是否已经销毁
        /// </summary>
        protected bool _disposed;
        /// <summary>
        /// 取消token
        /// </summary>
        protected readonly CancellationTokenSource _cancellToken = new();

        /// <summary>
        /// 日志对象
        /// </summary>
        protected readonly AbsGCCLogger _logger;

        /// <summary>
        /// 是否运行中
        /// </summary>
        protected bool _running;


        /// <summary>
        /// server端对象
        /// </summary>
        protected AbsCommUSBClient<T> _usbServer;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志模块实例</param>
        /// <param name="name">名称</param>
        public AbsCommUSBServer(string name, AbsGCCLogger logger)
        {
            ServerType = "COM";
            _logger = logger;
            Name = name;
            _usbServer = GetServer(name);
            _usbServer.OnDisposing += () =>
            {
                this.Dispose();
            };
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~AbsCommUSBServer()
        {
            Dispose(false);
        }

        /// <summary>
        /// 销毁模型
        /// </summary>
        /// <param name="flag">是否是用户主动调用</param>
        protected virtual void Dispose(bool flag)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;


            try
            {
                if (_usbServer != null)
                {
                    _usbServer.Dispose();
                }
                _cancellToken.Cancel();
                _cancellToken.Dispose();
            }
            catch (Exception ex)
            {
                _logger.Error("AbsCommTcpClient dispose error.", exception: ex);
            }
        }

        /// <summary>
        /// 销毁模型
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }


        /// <summary>
        /// 启动服务
        /// </summary> 
        /// <param name="pid">PID</param>
        /// <param name="vid">vid</param>
        /// <param name="readEndPoint">读入口</param>
        /// <param name="writeEndPoint">写入口</param>
        public AbsCommUSBClient<T>? Bind(int pid, int vid, ReadEndpointID readEndPoint, WriteEndpointID writeEndPoint)
        {
            if (!_running)
            {
                lock (this)
                {
                    if (!_running)
                    {
                        _usbServer.BindTo(pid, vid, readEndPoint, writeEndPoint);
                        _running = true;
                    }
                }
            }
            return _usbServer;
        }



        /// <summary>
        /// 获取一个当前服务的客户端
        /// </summary>
        /// <param name="name">名称</param> 
        /// <returns></returns>
        protected abstract AbsCommUSBClient<T> GetServer(string name);

        /// <summary>
        /// 获取一个服务器专用客户端
        /// </summary>
        /// <param name="name">名称</param> 
        /// <returns></returns>
        protected abstract AbsCommUSBClient<T> GetServerClient(string name);
    }
}
